using BiologicalResearch.Data;
using BiologicalResearch.Interfaces;
using BiologicalResearch.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BiologicalResearch.Services
{
    public class AgentService : IAgentService
    {
        private readonly ResearchContext _context;

        public AgentService(ResearchContext context)
        {
            _context = context;
        }

        public async Task<ResearchAgent> CreateAgentAsync(string specialization)
        {
            var agent = new ResearchAgent
            {
                Id = $"Agent-{Guid.NewGuid()}",
                EnergyLevel = 100,
                LastActive = DateTime.UtcNow,
                Specialization = specialization
            };

            _context.Agents.Add(agent);
            await _context.SaveChangesAsync();

            return agent;
        }

        public async Task<ResearchAgent> GetAgentAsync(string agentId)
        {
            return await _context.Agents
                .Include(a => a.Experiments)
                .Include(a => a.Findings)
                .FirstOrDefaultAsync(a => a.Id == agentId);
        }

        public async Task UpdateAgentAsync(ResearchAgent agent)
        {
            agent.LastActive = DateTime.UtcNow;
            _context.Agents.Update(agent);
            await _context.SaveChangesAsync();
        }

        public async Task<Experiment> StartExperimentAsync(string agentId, string topic)
        {
            var agent = await GetAgentAsync(agentId);
            if (agent == null)
                throw new KeyNotFoundException("Agent not found");

            var experiment = new Experiment
            {
                Topic = topic,
                StartTime = DateTime.UtcNow,
                Status = "InProgress",
                AgentId = agentId
            };

            _context.Experiments.Add(experiment);
            await _context.SaveChangesAsync();

            return experiment;
        }

        public async Task CompleteExperimentAsync(int experimentId)
        {
            var experiment = await _context.Experiments.FindAsync(experimentId);
            if (experiment != null)
            {
                experiment.EndTime = DateTime.UtcNow;
                experiment.Status = "Completed";
                await _context.SaveChangesAsync();
            }
        }

        public async Task<ResearchFinding> RecordFindingAsync(
            string agentId, 
            int experimentId, 
            string content, 
            int significance)
        {
            var finding = new ResearchFinding
            {
                Content = content,
                Significance = significance,
                RecordedAt = DateTime.UtcNow,
                AgentId = agentId,
                ExperimentId = experimentId
            };

            _context.Findings.Add(finding);
            await _context.SaveChangesAsync();

            return finding;
        }

        public async Task<List<ResearchFinding>> CollaborateAsync(
            List<string> agentIds, 
            string researchTopic)
        {
            var findings = new List<ResearchFinding>();
            var experiment = await StartExperimentAsync(agentIds.First(), researchTopic);

            foreach (var agentId in agentIds)
            {
                var agent = await GetAgentAsync(agentId);
                if (agent != null && agent.EnergyLevel > 20)
                {
                    agent.EnergyLevel -= 20;
                    var finding = await RecordFindingAsync(
                        agentId,
                        experiment.Id,
                        $"Collaborative finding on {researchTopic} from {agentId}",
                        new Random().Next(1, 5));
                    
                    findings.Add(finding);
                    await UpdateAgentAsync(agent);
                }
            }

            await CompleteExperimentAsync(experiment.Id);
            return findings;
        }
    }
}